#!/usr/bin/env python
# 
# Dialogs.py - Contains the code for the dialogs used in PecPlot
#

import wx
import os
#import parse
import ConfigParser

from ValuePanel import MultiValuePanel
from ValuePanel import ValuePanel
from Converters import UnitConverter


uConv = UnitConverter()
uDict = uConv.getUnits()

class UnitPanel(wx.Panel):
    
    def __init__(self, parent, defaults=None, bstr='Output', *args, **kwds):
        wx.Panel.__init__(self, parent, *args, **kwds)      
        self.rbox = wx.ComboBox(self, wx.ID_ANY, choices=uDict['Radius'], 
                                  style=wx.CB_DROPDOWN | wx.CB_READONLY)        
        self.ebox = wx.ComboBox(self, wx.ID_ANY, choices=uDict['Energy'], 
                                style=wx.CB_DROPDOWN | wx.CB_READONLY)
        self.obox = wx.ComboBox(self, wx.ID_ANY, choices=["Atomic", "Molecular"], 
                                    style=wx.CB_DROPDOWN | wx.CB_DROPDOWN | wx.CB_READONLY)
        self.setUnits(defaults)
        
        self.rtext = wx.StaticText(self, wx.ID_ANY, "Radius: ")
        self.etext = wx.StaticText(self, wx.ID_ANY, "Energy: ")
        self.otext = wx.StaticText(self, wx.ID_ANY, "Scale: ")
        
        btext = bstr + " Units"
        static = wx.StaticBox(self, wx.ID_ANY, btext)
        static.Lower()
        bsizer = wx.StaticBoxSizer(static, wx.HORIZONTAL)
                     
        self.sizer = wx.BoxSizer(wx.HORIZONTAL)
        rsizer = wx.BoxSizer(wx.VERTICAL)
        esizer = wx.BoxSizer(wx.VERTICAL)
        osizer = wx.BoxSizer(wx.VERTICAL)

        rsizer.Add(self.rtext, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        rsizer.Add(self.rbox, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        bsizer.Add(rsizer, wx.ALL, 5)

        esizer.Add(self.etext, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        esizer.Add(self.ebox, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        bsizer.Add(esizer, wx.ALL, 5)
        
        osizer.Add(self.otext, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        osizer.Add(self.obox, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        bsizer.Add(osizer, wx.ALL, 5)
       
        self.sizer.Add(bsizer, 0, wx.EXPAND)
        self.SetSizer(self.sizer)
        self.sizer.Fit(self)      
        
    def setUnits(self, units):
        if units == None:
            self.rbox.SetSelection(0)
            self.ebox.SetSelection(0)
            self.obox.SetSelection(0)
        
        else:
            self.rbox.SetStringSelection(units['Radius'])
            self.ebox.SetStringSelection(units['Energy'])
            self.obox.SetStringSelection(units['Scale'])

    def getUnits(self):
        r = self.rbox.GetValue()
        e = self.ebox.GetValue()
        s = self.obox.GetValue()           
        return dict([('Radius', r), ('Energy', e), ('Scale', s)])

    def getUnitsList(self):
        r = self.rbox.GetValue()
        e = self.ebox.GetValue()
        s = self.obox.GetValue()           
        return [r, e, s]

class FilePanel(wx.Panel):
    def __init__(self, parent, currents, *args, **kwds):
        wx.Panel.__init__(self, parent, *args, **kwds )
        self.fstring = currents['fstring']
        self.units = currents['units']
        self.states = currents['states']     
        self.fprops = ('#', 0)
    
        self.statebox = wx.ListCtrl(self, wx.ID_ANY, style=wx.LC_EDIT_LABELS | wx.LC_REPORT | wx.LC_HRULES )        
        self.statebox.InsertColumn(0, "State", width = 60)       
        self.statebox.InsertColumn(1, "File", width = 250)
        self.statebox.InsertColumn(2, "Radius Unit", wx.LIST_FORMAT_RIGHT, width = 100 )
        self.statebox.InsertColumn(3, "Energy Unit",  wx.LIST_FORMAT_RIGHT, width = 120)
        self.statebox.InsertColumn(4, "Energy Scale",  wx.LIST_FORMAT_RIGHT, width = 120)
        self.add_button = wx.Button(self, wx.ID_ANY, "Add")
        self.rem_button = wx.Button(self, wx.ID_ANY, "Remove")
        self.clear_button = wx.Button(self, wx.ID_ANY, "Clear")
        self.line = wx.StaticLine(self, wx.ID_ANY)
        self.ftext = wx.StaticText(self, wx.ID_ANY, "Format String")
        self.fstringbox = wx.TextCtrl(self, wx.ID_ANY, self.fstring)
        self.file_sizer_staticbox = wx.StaticBox(self, wx.ID_ANY, "Data Files")
        
        self.__set_properties()
        self.__do_layout()

        
        self.Bind(wx.EVT_BUTTON, self.OnAdd, self.add_button)
        self.Bind(wx.EVT_BUTTON, self.OnRem, self.rem_button)
        self.Bind(wx.EVT_BUTTON, self.OnClear, self.clear_button)
        # end wxGlade

    def __set_properties(self):
        self.datafiles = []        
        for state in self.states:
            additem = [state.label]
            for item in state.fileinfo:
                additem.append(item)
            self.datafiles.append(additem) 
            self.statebox.Append(additem)                
        return
        
    def __do_layout(self):
        # begin wxGlade: MyFrame2.__do_layout
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.file_sizer_staticbox.Lower()
        file_sizer = wx.StaticBoxSizer(self.file_sizer_staticbox, wx.HORIZONTAL)
        button_sizer = wx.BoxSizer(wx.VERTICAL)
        file_sizer.Add(self.statebox, 4, wx.ALL | wx.EXPAND | wx.GROW | wx.ALIGN_CENTER_VERTICAL, 5)
        button_sizer.Add(self.add_button, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        button_sizer.Add(self.rem_button, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        button_sizer.Add(self.clear_button, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        button_sizer.Add(self.line, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)        
        button_sizer.Add(self.ftext, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        button_sizer.Add(self.fstringbox, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)        
        
        file_sizer.Add(button_sizer, 0, wx.EXPAND | wx.ALL, 5)
        sizer.Add(file_sizer, 2, wx.EXPAND | wx.GROW | wx.ALL, 5)
        
        self.SetSizer(sizer)
        sizer.Fit(self)
        self.Layout()

    def OnAdd(self, event): 
        '''Opens an AddStateDialog'''
        dlg = AddStateDialog(self, self.fstringbox.GetValue(), units=self.units, fprops = self.fprops)
        if dlg.ShowModal() == wx.ID_OK:
            output = dlg.GetOutput()
            #make sure an item isnt being added twice
            for i in range(len(self.datafiles)):
                if output[0] == self.datafiles[i][0]:
                    wx.MessageBox("Item Already Added!")
                    return
            self.datafiles.append(output) 
            self.statebox.Append(output[:-2])
            self.units = dlg.unitPanel.getUnits()
            self.fprops = output[-2:]
            
        dlg.Destroy()
        
    def OnClear(self, event):
        self.statebox.ClearAll()
        self.datafiles = []
      
    def OnRem(self, event):  
        selections = self.getSelected()
        for item in selections:
            self.statebox.DeleteItem(item)
            self.datafiles.pop(item)
            
    def getOutput(self):
        return self.fstringbox.GetValue(), self.datafiles
            
    def getSelected(self):
        sel = []
        item = self.statebox.GetFirstSelected()
        if item >= 0:
            sel.append(item)
        nxt = self.statebox.GetNextSelected(item)
        while nxt >= 0:
            sel.append(nxt)
            nxt = self.statebox.GetNextSelected(nxt)
        return sel
    
class AxPanel(wx.Panel):
    def __init__(self, parent, currentvals, *args, **kwds):
        wx.Panel.__init__(self, parent, *args, **kwds)
        self.fields = []
        self.titles = ("Horizontal", "Vertical")
        
        self.fields.append( (('xmin', 'Minimum Internuclear Distance'), 
                     ('xmax', 'Maximum Internuclear Distance'),
                     ('xticks', 'Radial Axis Ticks Spacing')) )
        self.fields.append( (('ymin', 'Minimum Energy'), 
                          ('ymax', 'Maximum Energy'),
                          ('yticks', 'Energy Axis Ticks Spacing')) )
        self.types = {'xmin': float, 'xmax': float, 'xticks': float,
                     'ymax': float, 'ymin': float, 'yticks': float }
        self.vpanel = MultiValuePanel(self, self.fields, self.titles, currentvals)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.vpanel, 0, wx.ALL | wx.EXPAND, 5)
        self.SetSizer(sizer)
        sizer.Fit(self)
        
        
    def sanityChecks(self):
        '''Defines input checks and error messages'''

        tests = (("xmin > xmax", 'Minimum Radius must be less than maximum Radius'))
        msg = self.mpanel.panels[0].checkInput(self.types, tests=tests)
        if msg: return msg
        
        tests = (("ymin > ymax", 'Minimum energy must be less than maximum energy'))
        msg = self.mpanel.panels[1].checkInput(self.types, tests=tests)

        return msg

class WinPanel(wx.Panel):
    def __init__(self, parent, currentvals, currentunits, *args, **kwds):
        wx.Panel.__init__(self, parent, *args, **kwds)
        self.fields = []
        self.titles = ("Horizontal", "Vertical")
        
        self.fields.append( (('xmin', 'Minimum Internuclear Distance'), 
                     ('xmax', 'Maximum Internuclear Distance')) )
        self.fields.append( (('ymin', 'Minimum Energy'), 
                          ('ymax', 'Maximum Energy')) )
        self.types = {'xmin': float, 'xmax': float, 
                     'ymax': float, 'ymin': float}
        self.vpanel = MultiValuePanel(self, self.fields, self.titles, currentvals)
        self.upanel = UnitPanel(self, defaults=currentunits)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.vpanel, 0, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.upanel, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        self.SetSizer(sizer)
        sizer.Fit(self)

    def sanityChecks(self):
        '''Defines input checks and error messages'''

        tests = (("xmin > xmax", 'Minimum Radius must be less than maximum Radius'))
        msg = self.mpanel.panels[0].checkInput(self.types, tests=tests)
        if msg: return msg
        
        tests = (("ymin > ymax", 'Minimum energy must be less than maximum energy'))
        msg = self.mpanel.panels[1].checkInput(self.types, tests=tests)

        return msg

    def getOutput(self, dtypes):
        windict = self.vpanel.getOutput(dtypes)
        units = self.upanel.getUnits()
        return windict, units

class StatesDialog(wx.Dialog):
    def __init__(self, parent, units, fstring, states=[], *args, **kwds):
        # begin wxGlade: WinDialog.__init__

        wx.Dialog.__init__(self, parent, *args, **kwds)
        
        self.SetTitle("Add/Remove States")
        self.filepanel = FilePanel(self, units, fstring, states=states)
        
        ok_button = wx.Button(self, wx.ID_OK, "Ok")
        canc_button = wx.Button(self, wx.ID_CANCEL, "Cancel")
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_sizer.Add(ok_button, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
        button_sizer.Add(canc_button, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)        
        sizer.Add(self.filepanel, 2, wx.ALL | wx.EXPAND | wx.GROW, 5)
        sizer.Add(button_sizer, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
        self.SetSizer(sizer)
        sizer.Fit(self)
        self.Layout()
        self.SetSize((600, 300))
        
        self.Bind(wx.EVT_BUTTON, self.OnOk, ok_button)
        self.Bind(wx.EVT_BUTTON, self.OnCancel, canc_button)
        
    def OnOk(self, event):  
        self.EndModal(wx.ID_OK)
        

    def OnCancel(self, event):  # wxGlade: WinDialog.<event_handler>
        self.EndModal(wx.ID_CANCEL)

class SizeDialog(wx.Dialog):
    def __init__(self, parent, figure, *args, **kwds):
        wx.Dialog.__init__(self, parent, *args, **kwds)
        
        self.SetTitle("Set Output Size")
        ok_button = wx.Button(self, wx.ID_OK, "Ok")
        canc_button = wx.Button(self, wx.ID_CANCEL, "Cancel")
        size = figure.get_size_inches()
        self.currents = {'Width': size[0], 'Height': size[1]}
        self.fields = [ ('Width', 'Width in inches'), ('Height', 'Height in inches') ]
        self.vpanel = ValuePanel(self, self.fields, self.currents)
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_sizer.Add(ok_button, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
        button_sizer.Add(canc_button, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)        
        
        sizer.Add(self.vpanel, 2, wx.ALL | wx.EXPAND | wx.GROW, 5)
        sizer.Add(button_sizer, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
        self.SetSizer(sizer)
        sizer.Fit(self)
        self.Layout()
        #self.SetSize((600, 300))
        
        self.Bind(wx.EVT_BUTTON, self.OnOk, ok_button)
        self.Bind(wx.EVT_BUTTON, self.OnCancel, canc_button)
        
    def OnOk(self, event):  
        self.EndModal(wx.ID_OK)
        
    def getOutput(self):
        return self.vpanel.getProps({'Width': float, 'Height': float})
        
    def OnCancel(self, event):  # wxGlade: WinDialog.<event_handler>
        self.EndModal(wx.ID_CANCEL)



def guess(label):

    #multiplicity

    mult = ''
    fc = label[0]
    tests = {'Singlet': ('s', 'S', '1'),
             'Doublet': ('d', 'D', '2'),
             'Triplet': ('t', 'T', '3'),
             }
    for key in tests:
        if fc in tests[key]:
            mult = key

    rsym = ''
    remaining = label[1:]
    
    repl = []
    
    if 'u' in remaining.lower():
        rsym = 'u'
        repl = 'u'
    elif 'g' in remaining.lower():
        rsym = 'g'
        repl = 'g'
    sym = ''
    rem = remaining.replace(repl, "")
    if '+' in rem:
        sym = '+'
        repl = '+'
    if '-' in rem:
        sym = '-'
        repl = '-'
    rem1 = rem.replace(repl, "")

    term = ''
    tests = {'Sigma': ('s', 'sigma'), 'Delta': ('d', 'delta'), 'Pi' : ('p', 'pi'),
             'Phi' : ('f', 'phi', 'fi') }
    for key in tests:
        if rem1.lower() in tests[key]:
            term = key
            
    return (mult, term, rsym, sym)

class AddStateDialog(wx.Dialog):
    def __init__(self, parent, fstring, units=None, fprops = ('#', 0), *args, **kwds):
        # begin wxGlade: AddStateDia.__init__
        kwds["style"] = wx.DEFAULT_DIALOG_STYLE
        wx.Dialog.__init__(self, parent, *args, **kwds)
        self.label = ''
        self.fstring = fstring
        self.flabel = wx.StaticText(self, -1, "Filename: ")
        self.filebox = wx.TextCtrl(self, -1, "")
        self.browsebutton = wx.Button(self, -1, "Browse...")
        self.file_sizer_staticbox = wx.StaticBox(self, -1, "File")
        self.multlabel = wx.StaticText(self, -1, "Multiplicity")
        self.multbox = wx.Choice(self, -1, choices=["Singlet", "Doublet", "Triplet"])
        self.termlabel = wx.StaticText(self, -1, "Term")
        self.termbox = wx.Choice(self, -1, choices=["Sigma", "Pi", "Delta", "Phi"])
        self.symlabel = wx.StaticText(self, -1, "Symmetry")
        self.symbox = wx.Choice(self, -1, choices=["u", "g"])
        self.symbox2 = wx.Choice(self, -1, choices=["", "+", "-"])
        self.clabel= wx.StaticText(self, -1, "Comment Character")
        self.cbox = wx.TextCtrl(self, -1, "")
        self.srlabel = wx.StaticText(self, -1, "Skip Rows")
        self.srbox = wx.TextCtrl(self, -1, "")
        self.label_sizer_staticbox = wx.StaticBox(self, -1, "State Label")
        self.unitPanel = UnitPanel(self, units, bstr='Input')
        self.okbutton = wx.Button(self, -1, "Ok")
        self.cancelbutton = wx.Button(self, -1, "Cancel")

        self.__set_properties(fprops)
        self.__do_layout()

        self.Bind(wx.EVT_BUTTON, self.OnOk, self.okbutton)
        self.Bind(wx.EVT_BUTTON, self.OnCancel, self.cancelbutton)
        self.Bind(wx.EVT_BUTTON, self.OnBrowse, self.browsebutton)
        # end wxGlade

    def __set_properties(self, fileprops):
        # begin wxGlade: AddStateDia.__set_properties
        self.SetTitle("Add State")
        self.multbox.SetSelection(0)
        self.termbox.SetSelection(0)
        self.symbox.SetSelection(0)
        self.cbox.SetValue(fileprops[0])
        self.srbox.SetValue(str(fileprops[1]))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: AddStateDia.__do_layout
        sizer = wx.BoxSizer(wx.VERTICAL)
        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.label_sizer_staticbox.Lower()
        label_sizer = wx.StaticBoxSizer(self.label_sizer_staticbox, wx.HORIZONTAL)
        barsizer = wx.BoxSizer(wx.HORIZONTAL)
        propsizer = wx.BoxSizer(wx.HORIZONTAL)
        sym_sizer = wx.BoxSizer(wx.VERTICAL)
        term_sizer = wx.BoxSizer(wx.VERTICAL)
        mult_sizer = wx.BoxSizer(wx.VERTICAL)
        sb_sizer  = wx.BoxSizer(wx.HORIZONTAL)        
        self.file_sizer_staticbox.Lower()
        file_sizer = wx.StaticBoxSizer(self.file_sizer_staticbox, wx.VERTICAL)
        
        barsizer.Add(self.flabel, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        barsizer.Add(self.filebox, 2, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        barsizer.Add(self.browsebutton, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        propsizer.Add(self.clabel, 0 , wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        propsizer.Add(self.cbox, 0 , wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)        
        propsizer.Add(self.srlabel, 0 , wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        propsizer.Add(self.srbox, 0 , wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)        
        file_sizer.Add(barsizer, 0, wx.ALL | wx.EXPAND, 5)        
        file_sizer.Add(propsizer, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
        
        sizer.Add(file_sizer, 1, wx.EXPAND | wx.ALL, 5)
        mult_sizer.Add(self.multlabel, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        mult_sizer.Add(self.multbox, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        label_sizer.Add(mult_sizer, 1, wx.EXPAND, 0)
        term_sizer.Add(self.termlabel, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        term_sizer.Add(self.termbox, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        label_sizer.Add(term_sizer, 1, wx.EXPAND, 0)
        sym_sizer.Add(self.symlabel, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        
        sb_sizer.Add(self.symbox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)        
        sb_sizer.Add(self.symbox2, 0, wx.ALL| wx.ALIGN_CENTER_VERTICAL)
        sym_sizer.Add(sb_sizer, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        label_sizer.Add(sym_sizer, 1, wx.EXPAND, 0)
        sizer.Add(label_sizer, 1, wx.ALL | wx.EXPAND, 5)
        sizer.Add(self.unitPanel, 1, wx.ALL, 5)
        button_sizer.Add(self.okbutton, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        button_sizer.Add(self.cancelbutton, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        sizer.Add(button_sizer, 0, wx.ALIGN_RIGHT, 5)
        self.SetSizer(sizer)
        sizer.Fit(self)
        self.Layout()
        # end wxGlade
        
    def OnBrowse(self, event):  # wxGlade: AddDia.<event_handler>
        wildcard = "Text File (*.txt)|*.txt|" \
                   "Dat File (*.dat)|*.dat|" \
                   "All Files (*.*)|*.*"
        
        dlg = wx.FileDialog(
            self, message="Choose a file",
            defaultDir=os.getcwd(), 
            defaultFile="",
            wildcard=wildcard,
            style=wx.OPEN | wx.CHANGE_DIR 
            )

        if dlg.ShowModal() == wx.ID_OK:
            self.path = dlg.GetPath()
            self.head, self.tail = os.path.split(self.path)
            self.filebox.SetValue(self.tail)
            #s = parse.parse(self.fstring, self.tail)
            #values = guess(s[0]) 
            #self.setBoxes(values)
        dlg.Destroy()
        
    def OnOk(self, event):  # wxGlade: AddDia.<event_handler>
        if self.filebox.GetValue() == '':
            dlg = wx.MessageDialog(self, 'No File Chosen', 'Error', wx.OK)
            dlg.ShowModal()
            dlg.Destroy()
            return
        self.EndModal(wx.ID_OK)
       
    def OnCancel(self, event):  # wxGlade: AddDia.<event_handler>
        self.Close(True)

    def setBoxes(self, values):
        boxes = [self.multbox, self.termbox, self.symbox, self.symbox2]
        for i, box in enumerate(boxes):
            box.SetStringSelection(values[i])
        
    def GetOutput(self):
        terms = ['S', 'P', 'D', 'F']               

        self.label += str(self.multbox.GetSelection() + 1) + terms[self.termbox.GetSelection()] \
                    + self.symbox2.GetStringSelection() + self.symbox.GetStringSelection()
        units = self.unitPanel.getUnitsList() 
        comment = self.cbox.GetValue()
        skip = int(self.srbox.GetValue())
        ret = (self.label, self.path, units[0], units[1], units[2], comment, skip)
        return ret

class StylePanel(wx.Panel):
    def __init__(self, parent, currents, *args, **kwds):
        wx.Panel.__init__(self, parent, *args, **kwds)

        self.sigma = wx.StaticText(self, -1, "Sigma: ", style=wx.ALIGN_CENTRE)
        self.sbox = wx.ComboBox(self, wx.ID_ANY, choices=["black", "green", "red", "cyan", "magenta", "yellow", "blue", "white", "more..."], style=wx.CB_DROPDOWN | wx.CB_DROPDOWN | wx.CB_READONLY)
        self.delta = wx.StaticText(self, -1, "Delta: ", style=wx.ALIGN_CENTRE)
        self.dbox = wx.ComboBox(self, wx.ID_ANY, choices=["black", "green", "red", "cyan", "magenta", "yellow", "blue", "white", "more..."], style=wx.CB_DROPDOWN | wx.CB_DROPDOWN | wx.CB_READONLY)
        self.pi = wx.StaticText(self, -1, "Pi: ", style=wx.ALIGN_CENTRE)
        self.pbox = wx.ComboBox(self, wx.ID_ANY, choices=["black", "green", "red", "cyan", "magenta", "yellow", "blue", "white", "more..."], style=wx.CB_DROPDOWN | wx.CB_DROPDOWN | wx.CB_READONLY)
        self.phi = wx.StaticText(self, -1, "Phi: ", style=wx.ALIGN_CENTRE)
        self.fbox = wx.ComboBox(self, wx.ID_ANY, choices=["black", "green", "red", "cyan", "magenta", "yellow", "blue", "white", "more..."], style=wx.CB_DROPDOWN | wx.CB_DROPDOWN | wx.CB_READONLY)
        self.color_sizer_staticbox = wx.StaticBox(self, -1, "Colors")
        self.singlet = wx.StaticText(self, -1, "Singlet: ", style=wx.ALIGN_CENTRE)
        self.singbox = wx.ComboBox(self, -1, choices=["-", "--", "-.", ":"], style=wx.CB_DROPDOWN | wx.CB_DROPDOWN | wx.CB_READONLY)
        self.doublet = wx.StaticText(self, -1, "Doublet: ", style=wx.ALIGN_CENTRE)
        self.doubbox = wx.ComboBox(self, -1, choices=["-", "--", "-.", ":"], style=wx.CB_DROPDOWN | wx.CB_DROPDOWN | wx.CB_READONLY)
        self.triplet = wx.StaticText(self, -1, "Triplet: ", style=wx.ALIGN_CENTRE)
        self.tripbox = wx.ComboBox(self, -1, choices=["-", "--", "-.", ":"], style=wx.CB_DROPDOWN | wx.CB_DROPDOWN | wx.CB_READONLY)
        self.style_sizer_staticbox = wx.StaticBox(self, -1, "Styles")
        self.gerade = wx.StaticText(self, -1, "Gerade: ", style=wx.ALIGN_CENTRE)
        self.gbox = wx.ComboBox(self, -1, choices=["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"], style=wx.CB_DROPDOWN | wx.CB_DROPDOWN)
        self.ungerade = wx.StaticText(self, -1, "Ungerade: ", style=wx.ALIGN_CENTRE)
        self.ubox = wx.ComboBox(self, -1, choices=["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"], style=wx.CB_DROPDOWN | wx.CB_DROPDOWN)
        self.width_sizer_staticbox = wx.StaticBox(self, -1, "Linewidth")

        self.__set_properties(currents)
        self.__do_layout()

        self.Bind(wx.EVT_COMBOBOX, self.OnBox, self.sbox)
        self.Bind(wx.EVT_COMBOBOX, self.OnBox, self.dbox)
        self.Bind(wx.EVT_COMBOBOX, self.OnBox, self.pbox)
        self.Bind(wx.EVT_COMBOBOX, self.OnBox, self.fbox)
        

    def __set_properties(self, currents):
        #set defaults
        self.sbox.SetValue(currents['S'])
        self.dbox.SetValue(currents['D'])
        self.pbox.SetValue(currents['P'])
        self.fbox.SetValue(currents['F'])
        self.singbox.SetStringSelection(currents['Singlets'])
        self.doubbox.SetStringSelection(currents['Doublets'])
        self.tripbox.SetStringSelection(currents['Triplets'])
        self.gbox.SetValue(currents['Gerade'])
        self.ubox.SetValue(currents['Ungerade'])
  

    def __do_layout(self):
        self.width_sizer_staticbox.Lower()
        width_sizer = wx.StaticBoxSizer(self.width_sizer_staticbox, wx.HORIZONTAL)
        width_grid = wx.GridSizer(2, 2, 0, 0)
        self.style_sizer_staticbox.Lower()
        style_sizer = wx.StaticBoxSizer(self.style_sizer_staticbox, wx.HORIZONTAL)
        style_grid = wx.GridSizer(2, 4, 0, 0)
        self.color_sizer_staticbox.Lower()
        color_sizer = wx.StaticBoxSizer(self.color_sizer_staticbox, wx.HORIZONTAL)
        state_grid = wx.GridSizer(2, 4, 0, 0)
        state_grid.Add(self.sigma, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
        state_grid.Add(self.sbox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        state_grid.Add(self.delta, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
        state_grid.Add(self.dbox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        state_grid.Add(self.pi, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
        state_grid.Add(self.pbox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        state_grid.Add(self.phi, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
        state_grid.Add(self.fbox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        color_sizer.Add(state_grid, 1, wx.EXPAND, 0)
        
        style_grid.Add(self.singlet, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
        style_grid.Add(self.singbox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        style_grid.Add(self.doublet, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
        style_grid.Add(self.doubbox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        style_grid.Add(self.triplet, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
        style_grid.Add(self.tripbox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        style_sizer.Add(style_grid, 1, wx.EXPAND, 0)
        
        width_grid.Add(self.gerade, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
        width_grid.Add(self.gbox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        width_grid.Add(self.ungerade, 0, wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL, 5)
        width_grid.Add(self.ubox, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        width_sizer.Add(width_grid, 1, wx.EXPAND, 0)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(color_sizer, 1, wx.ALL | wx.EXPAND, 2)
        self.sizer.Add(style_sizer, 1, wx.ALL | wx.EXPAND, 1)
        self.sizer.Add(width_sizer, 1, wx.ALL | wx.EXPAND, 0)
        self.SetSizer(self.sizer)
        self.sizer.Fit(self)
        self.Layout()
        # end wxGlade

    def OnBox(self, event):  
        '''Box seletion event handler.  When more... is chosen from one of the 
        color dropdowns, creates a color choice dialog'''
        box = event.GetEventObject()
        mpos = box.FindString("more...")        
        
        if event.GetSelection() == mpos:
            dlg = wx.ColourDialog(self)
            dlg.GetColourData().SetChooseFull(True)
 
            if dlg.ShowModal() == wx.ID_OK:
                data = dlg.GetColourData()
                box.Insert(data.GetColour().GetAsString(flags = wx.C2S_NAME | wx.C2S_HTML_SYNTAX), mpos)
                box.SetSelection(mpos)
     
            dlg.Destroy()
       

        
    def sanity_check(self):
        '''Makes sure input makes sense.  If an error is detected, returns a string
        describing the error(returns on first error found)'''
        cdict = {"Sigma": self.sbox.GetValue(), "Delta": self.dbox.GetValue(), "Pi": self.pbox.GetValue(), "Phi": self.fbox.GetValue() }        
        for k in cdict:
            if cdict[k] == '':
                return 'Missing color for ' + k + ' states'
        
        lsdict = {"Ungerade" : self.ubox.GetValue(), "Gerade" : self.gbox.GetValue()}
        for k in lsdict:
            if lsdict[k] == '':
                return 'Missing linewidth for ' + k + ' states'
            try:
                f = float(lsdict[k])
            except ValueError:
                return 'Invalid linewidth for ' + k + ' states'
        
        return ''
        
    def getOutput(self):
        labels = ["S", "P", "D", "F", "Singlets", "Doublets", "Triplets",
                  "Gerade", "Ungerade"]
        vals = [self.sbox.GetValue(), self.pbox.GetValue(), self.dbox.GetValue(), 
                self.fbox.GetValue(), self.singbox.GetValue(), self.doubbox.GetValue(),
                self.tripbox.GetValue(), self.gbox.GetValue(), self.ubox.GetValue() ]
        return dict(zip(labels, vals))
        

class DisPanel(wx.Panel):
    def __init__(self, parent, currentmol="Rb2", *args, **kwds):
        wx.Panel.__init__(self, parent, *args, **kwds)
        
        self.mlabel = wx.StaticText(self, wx.ID_ANY, "Molecule Name: ")
        self.mbox = wx.Choice(self, wx.ID_ANY)        
        self.zlabel = wx.StaticText(self, wx.ID_ANY, "Ground State Energy: ")
        self.ztext = wx.StaticText(self, wx.ID_ANY, "")
        self.dissbox = wx.ListBox(self, wx.ID_ANY, choices=[])
        self.stext = wx.StaticText(self, wx.ID_ANY, "Scale: ")
        self.utext = wx.StaticText(self, wx.ID_ANY, "Unit: ")
        self.diss_sizer_staticbox = wx.StaticBox(self, wx.ID_ANY, "Dissociation Limits")
        
        self.readMolData(currentmol)
        self.__do_layout()
        
        self.Bind(wx.EVT_CHOICE, self.OnSwitch, self.mbox)
        
    def OnSwitch(self, event):
        self.readMolData(self.mbox.GetStringSelection())
        
    def readMolData(self, molname):
        limits = {}
        filename = 'molecules.cfg'
        parser = ConfigParser.ConfigParser()
        parser.optionxform = str
        parser.read(filename)  
        supported_mols = parser.sections()
        options = parser.options(molname)
        ground = parser.getfloat(molname, options.pop(options.index('Ground State')))
        scale = parser.get(molname, options.pop(options.index('Scale')))
        unit = parser.get(molname, options.pop(options.index('Units')))
    
        for key in options:
            limits[key] = parser.getfloat(molname, key)       
        
        self.mbox.Clear()
        self.mbox.AppendItems(supported_mols)
        self.mbox.SetStringSelection(molname)      
        self.ztext.SetLabel(str(ground) + " " + unit)
        self.stext.SetLabel("Scale: " + scale)
        self.utext.SetLabel("Unit: " + unit)
        
        self.dissbox.Clear()
        sorted_limits = sorted(limits.items(), key=lambda x: x[1])
        for k in sorted_limits:
            self.dissbox.Append(k[0] + " : " + str(k[1]))

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.diss_sizer_staticbox.Lower()
        diss_sizer = wx.StaticBoxSizer(self.diss_sizer_staticbox, wx.HORIZONTAL)
        sc_sizer = wx.BoxSizer(wx.VERTICAL)
        mol_sizer = wx.GridSizer(2, 2, 0, 0)
        mol_sizer.Add(self.mlabel, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 5)
        mol_sizer.Add(self.mbox, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 5)
        mol_sizer.Add(self.zlabel, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 5)
        mol_sizer.Add(self.ztext, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 5)
        self.sizer.Add(mol_sizer, 0, wx.ALL, 5)
        diss_sizer.Add(self.dissbox, 0, wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL, 5)
        sc_sizer.Add(self.stext, 0, wx.ALL , 5)
        sc_sizer.Add(self.utext, 0, wx.ALL , 5)
        diss_sizer.Add(sc_sizer, 0, wx.ALL, 5)
        
        self.sizer.Add(diss_sizer, 1, wx.EXPAND | wx.ALL, 5)
        self.SetSizer(self.sizer)
        self.sizer.Fit(self)
        self.Layout()
        
    def getOutput(self):
        return self.mbox.GetStringSelection()
        
class SettingsNB(wx.Notebook):
    def __init__(self, parent, currents, units, *args, **kwds):
        wx.Notebook.__init__(self, parent, *args, **kwds)
        
        if units:
            self.units = units
        else:
            outunits = {"Radius": uDict['Radius'][0], "Energy": uDict['Energy'][0], "Scale": 'Molecular'}
            inunits = {"Radius": uDict['Radius'][0], "Energy": uDict['Energy'][0], "Scale": 'Molecular'}
            self.units = {'input': inunits, 'output': outunits} 
        if currents:
            self.currents = currents            
        else:
            self.currents = {'mol' :  'Rb2', 
                    'win': {'xmin': 0, 'xmax': 20, 'ymin': -5000, 'ymax': 30000},
                    'ax': {'xmin': 0, 'xmax': 20, 'ymin': 10000, 'ymax': 25000, 'xticks' : 2, 'yticks': 2000},
                    'files': { 'units' : self.units['input'], 'fstring':"{}.txt", "states": []} ,
                    'styles': {'Gerade': '1', 'Singlets': '-', 'D': 'blue', 'F': 'red', 'Doublets': '-.', 
                               'P': 'green', 'S': 'black', 'Ungerade': '2', 'Triplets': '--'} }

        self.molpage = DisPanel(self, currentmol=self.currents['mol'])
        self.AddPage(self.molpage, "Molecule")
 
        self.winpage = WinPanel(self, self.currents['win'], self.units['output'] )
        self.AddPage(self.winpage, "Virtual Window")
        
        self.axpage = AxPanel(self, self.currents['ax'])
        self.AddPage(self.axpage, "Visible Region")
        
        self.filepage = FilePanel(self, self.currents['files'])
        self.AddPage(self.filepage, "Data Files")
        
        self.stylepage = StylePanel(self, self.currents['styles'])
        self.AddPage(self.stylepage, "Colors and Styles")

class SettingsDlg(wx.Dialog):
    def __init__(self, parent, currents, units, *args, **kwds):
        '''currents is a dict of dicts corresponding to the current values of
        for each page in the notebook.  '''
        
        wx.Dialog.__init__(self, parent, *args, **kwds)
        self.nb = SettingsNB(self, currents, units)
        okb = wx.Button(self, wx.ID_OK, "Ok")
        cb = wx.Button(self, wx.ID_CANCEL, "Cancel")
        bsizer = wx.BoxSizer(wx.HORIZONTAL)
        bsizer.Add(okb, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        bsizer.Add(cb, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.nb, 1, wx.ALL | wx.EXPAND, 5)
        sizer.Add(bsizer, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
        self.Bind(wx.EVT_BUTTON, self.onOk, okb)
        self.Bind(wx.EVT_BUTTON, self.onCancel, cb)
        self.SetSizer(sizer)
        sizer.Fit(self)
        self.Layout()
        
    def onOk(self, event):
        self.EndModal(wx.ID_OK)
    
    def onCancel(self, event):
        self.EndModal(wx.ID_CANCEL)
        

    def getOutput(self):
        molname = self.nb.molpage.getOutput() #Dictionary of molecule info
        types = {'xmin': float, 'xmax': float, 'xticks': float,
                     'ymax': float, 'yticks': float, 'ymin' : float }        
        axdict = self.nb.axpage.vpanel.getOutput(types)
        windict, units = self.nb.winpage.getOutput(types)
        fstring, files = self.nb.filepage.getOutput()
        stylesdict = self.nb.stylepage.getOutput()
        return molname, axdict, windict, units, fstring, files, stylesdict
      
    def writeFile(self, filename):
        '''writes the input information as a PecPlot config file'''
        parser = ConfigParser.ConfigParser()
        parser.optionxform = str
        
        towrite = self.getOutput()
        parser.add_section("Molecule")
        parser.set("Molecule", "Name", towrite[0])

        
        parser.add_section("Window")
        for key in towrite[1]:
                parser.set("Window", key, towrite[1][key])

        parser.add_section("Virtual")        
        for key in towrite[2]:
                parser.set("Virtual", key, towrite[2][key])

        parser.add_section("Units")
        for key in towrite[3]:
            parser.set("Units", key, towrite[3][key])
            
        parser.add_section("Files")
        parser.set("Files", "Format", towrite[4])
        for fileinfo in towrite[5]:
            line = ''
            for item in fileinfo[1:-1]:
                line += item + ", "
            line += str(fileinfo[-1])
            parser.set("Files", fileinfo[0], line)
            
        parser.add_section("Styles")
        for key in towrite[6]:
            parser.set("Styles", key, towrite[6][key])
            
        with open(filename, 'wb') as configfile:
            parser.write(configfile)

  
if __name__ == '__main__':

    app = wx.PySimpleApp()  # Start the application
    wx.InitAllImageHandlers()
    dialog = SettingsDlg(None, None, None, -1, "Settings")
    #dialog = TestDlg(None, currents['win'], outunits, -1, "Testing...")
    app.SetTopWindow(dialog)
    if dialog.ShowModal() == wx.ID_OK:
        print dialog.getOutput()
        dialog.writeFile("dlgtest.pec")
        dialog.Close(True)
    else:
        dialog.Close(True)
    app.MainLoop()




